<template>
    <a-layout>
        <a-layout-content
                :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"
        >
            <p>
                <!-- 这里可以直接用一个name作为响应式变量，但考虑到后续可能通过多个参数来查询，为了扩展性，统一封装成一个param对象 -->
                <a-form layout="inline" :model="param">
                    <a-form-item>
                        <a-button type="primary" @click="handleQuery()">查询</a-button>
                    </a-form-item>
                    <a-form-item>
                        <a-button type="primary" @click="handleAdd">新增</a-button>
                    </a-form-item>
                </a-form>
            </p>
            <p>
                <a-alert message="小提示：这里的分类会显示到首页的侧边菜单" type="info" closable/>
            </p>
            <a-table
              v-if="level1.length > 0"
              :columns="columns"
              :data-source="level1"
              :row-key="record => record.id"
              :pagination="false"
              :loading="loading"
              :defaultExpandAllRows="true"
            >
                <template #action="{ text, record }">
                    <a-space size="small">
                        <a-button type="primary" @click="handleEdit(record)">编辑</a-button>
                        <a-popconfirm
                          title="删除后不可恢复，确认删除?"
                          ok-text="是"
                          cancel-text="否"
                          @confirm="handleDelete(record.id)"
                        >
                            <!-- 在 2.2.0 之后，危险成为一种按钮属性而不是按钮类型 -->
                            <a-button type="primary" danger>删除</a-button>
                        </a-popconfirm>
                    </a-space>
                </template>
            </a-table>
        </a-layout-content>
    </a-layout>
    <a-modal
      title="分类表单"
      v-model:visible="modalVisible"
      :confirm-loading="modalLoading"
      @ok="handleModalOk">
        <a-form :model="category" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
            <a-form-item label="名称">
                <a-input v-model:value="category.name" />
            </a-form-item>
            <a-form-item label="父分类">
                <a-select
                        ref="select"
                        v-model:value="category.parent"
                >
                    <!-- 固定一个值为0的选项，表示根节点，没有父分类 -->
                    <a-select-option value="0">
                        无
                    </a-select-option>
                    <!-- 从一级分类中遍历中所有父分类的id，编辑时不可选择自己作为自己的父分类（编辑时会将信息传入表单） -->
                    <a-select-option v-for="c in level1" :key="c.id" :value="c.id" :disabled="category.id === c.id">
                        {{c.name}}
                    </a-select-option>
                </a-select>
            </a-form-item>
            <a-form-item label="顺序">
                <a-input v-model:value="category.sort" />
            </a-form-item>
        </a-form>
    </a-modal>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref } from 'vue';
import axios from 'axios';
import { message } from 'ant-design-vue';
import {Tool} from "@/util/tool";

export default defineComponent({
  name: 'AdminCategory',
  setup() {
    const param = ref() ; // 定义一个响应式变量，并初始化为空。用于存放搜索框中的内容）
    param.value = {} ;           //若不初始化，页面加载时param.name会出错，因为页面加载时就会读取该属性值
    const categorys = ref(); // ref方式，实现数据绑定
    const loading = ref(false);
    /**
     * 一级分类树，children属性就是二级分类
     * [{
     *   id: "",
     *   name: "",'
     *   ...
     *   children: [{
     *     id: "",
     *     name: "",
     *     ...
     *   }]
     * }]
     */
    const level1 = ref(); // 一级分类树，children属性就是二级分类
    level1.value = [] ;

    const columns = [
      {
        title: '名称',
        dataIndex: 'name',
        key: 'name',
      },
      {
        title: '父分类',
        dataIndex: 'parent',
        key: 'parent',
      },
      {
        title: '顺序',
        dataIndex: 'sort',
        key: 'sort',
      },
      {
        title: 'Action',
        dataIndex: 'action',
        key: 'action',
        slots: { customRender: 'action' },
      },
    ];

    /** 数据查询 */
    const handleQuery = () => {
        loading.value = true;   // 加载中
        axios.get("/category/all").then((response) => {
            loading.value = false;  // 加载完成
            const data = response.data ;
            if(data.success){
                categorys.value = data.content ; //ref方式，赋值
                console.log("原始数组:" , categorys.value) ;

                //level1.value = [] ; // 先初始化成一个空数组，再给它赋值树形结构
                level1.value = Tool.array2Tree(categorys.value, 0) ; // 父id为0，表示根节点，即一级分类
                console.log("树形结构:" , level1) ;
            }else {
                message.error(data.message);
            }
        });
    };

    // ---- 表单 ----
    const category = ref({});
    const modalVisible = ref(false);
    const modalLoading = ref(false);
    const handleModalOk = () => {
        modalLoading.value = true;
        axios.post("/category/save", category.value).then((response) => {
            modalLoading.value = false;
            const data = response.data ; // data = CommonResp
            // 后台返回成功后，关闭Modal弹框，并刷新列表
            if(data.success){
                modalVisible.value = false;
                // 重新加载列表（新增或编辑后）
                handleQuery();
            }else {
                message.error(data.message);
            }
        });
    }

    /** 编辑 */
    const handleEdit = (record: any) => {
        modalVisible.value = true ;
        // record是响应式变量categorys中的记录，直接复制给category这个编辑框中的响应式变量，会导致编辑一半不保存直接关闭编辑框的情况下，categorys中的记录也会跟着变化
        // category.value = record ;
        category.value = Tool.copy(record) ; // 用对象拷贝，解决响应式变量复制的影响
    }

    /** 新增 */
    const handleAdd = () => {
        modalVisible.value = true ;
        category.value = {} ;
    }

    /** 删除 */
    const handleDelete = (id: number) => {
        axios.delete("/category/delete/" + id).then((response) => {
            const data = response.data ; // data = CommonResp
            // 删除成功后，刷新列表
            if(data.success){
                handleQuery();
            }else {
                message.error(data.message);
            }
        });
    }

    onMounted(() => {
        handleQuery() ;
    });

    return {
      param,
      //categorys,
      level1,
      columns,
      loading,
      handleQuery, // HTML中需要调用，所以要return出去

      handleEdit,
      handleAdd,
      handleDelete,

      category,
      modalVisible,
      modalLoading,
      handleModalOk
    };
  },

});
</script>

<style scoped>
    img {
        width: 50px;
        height: 50px;
    }
</style>